﻿// *----------------------------------------------------------------
// Copyright (C) 2017 通通优品
// 版权所有。
// 
// 类名：RedisCacheDatabaseProvider.cs
// 功能描述：TongTongMall.Redis
// 
// Create User：jym 2017/02/09
// 
// Edit User：UserName,EditTime
// Describe：Describe
// ----------------------------------------------------------------*/
using System;
using System.Collections.Generic;
using System.Configuration;
using StackExchange.Redis;
using TongTongMall.Dependecy;
using TongTongMall.Extensions;

namespace TongTongMall.Redis.Cache
{
    public class RedisCacheDatabaseProvider : IRedisCacheDatabaseProvider
    {
        private const string ConnectionStringKey = "TongTongMall.Redis.Cache";
        private const string EnableCacheKey = "TongTongMall.Redis.Cache.Enable";
        private const string DatabaseIdSettingKey = "TongTongMall.Redis.Cache.DatabaseId";

        private readonly Lazy<ConnectionMultiplexer> _connectionMultiplexer;
        
        /// <summary>
        /// 
        /// </summary>
        public RedisCacheDatabaseProvider()
        {
            _connectionMultiplexer = new Lazy<ConnectionMultiplexer>(CreateConnectionMultiplexer);

            _connectionMultiplexer.Value.ConnectionFailed += (sender, e) =>
            {
                throw new TongTongMallException("Redis to Server connection error！");
            };
        }
    

        public ConnectionMultiplexer ConnectionMultiplexer
        {
            get
            {
                return _connectionMultiplexer.Value;
            }
        }

        /// <summary>
        ///获取与redis的连接通道
        /// </summary>
        public IDatabase GetDatabase()
        {
            return _connectionMultiplexer.Value.GetDatabase(GetDatabaseId());
        }

        private void Value_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
        {
            
        }

        /// <summary>
        /// 返回多台redis服务器
        /// </summary>
        /// <returns></returns>
        public IList<IServer> GetServer()
        {
            
            var list = new List<IServer>();
            var multiplexer = _connectionMultiplexer.Value;
            
            foreach (var endPoint in multiplexer.GetEndPoints())
            {
                var server = multiplexer.GetServer(endPoint);
                if (!server.IsConnected || !server.Features.Scan)
                    continue;
                list.Add(server);
            }
            return list;
        }

        private static ConnectionMultiplexer CreateConnectionMultiplexer()
        {
            var config = ConfigurationOptions.Parse(GetConnectionString());
            var connect = ConnectionMultiplexer.Connect(config);
            return connect;
        }

        /// <summary>
        /// 获取配置文件中database Id
        /// </summary>
        /// <returns></returns>
        private static int GetDatabaseId()
        {
            var appSetting = ConfigurationManager.AppSettings[DatabaseIdSettingKey];
            if (appSetting.IsNullOrEmpty())
            {
                return -1;
            }

            int databaseId;
            if (!int.TryParse(appSetting, out databaseId))
            {
                return -1;
            }                   

            return databaseId;
        }

        private bool? _isReadForCache;
        public bool IsReadForCache
        {
            get
            {
                if (!_isReadForCache.HasValue)
                {
                    bool isEnable = false;
                    bool.TryParse(ConfigurationManager.AppSettings[EnableCacheKey], out isEnable);
                    _isReadForCache = isEnable;
                }
                return _isReadForCache.Value;
            }
        }


        /// <summary>
        /// 获取数据连接
        /// </summary>
        /// <returns></returns>
        private static string GetConnectionString()
        {
            var connStr = ConfigurationManager.ConnectionStrings[ConnectionStringKey];
            if (connStr == null || connStr.ConnectionString.IsNullOrWhiteSpace())
            {
                return "localhost";
            }

            return connStr.ConnectionString;
        }

    }
}
